home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Resource for Source: C/C++
/
Resource for Source - C-C++.iso
/
misc_src
/
dpmifi
/
fixdpmi.c
next >
Wrap
C/C++ Source or Header
|
1995-11-01
|
5KB
|
196 lines
/* FIXDPMI.C - Fixes Borland C++ 3.0 DPMILOAD.EXE
* to work properly under DESQVIEW
*
* DPMILOAD mishandled setting it's own termination address
* by setting only the OFFSET at PSP:000Ah instead of the
* entire FAR POINTER. Since DV intercepts all terminations,
* and DPMILOAD had already terminated once as a TSR, the
* SEGMENT of the termination address was pointing into DV
* code, so when the OFFSET only was changed before the second
* exit, the 4C00, INT 21 call exited to nonsense.
* This patch rearranges the portion of code which blew it
* and unloads the TSR DPMILOAD from memory correctly.
* This patch fixes DPMILOAD so you can load any DPMI BC++ 3.0 TOOL
* in a window under DV. The only unusual setting I use is Keyboard
* conflict 8. The IDE still likes to steal some of the <ALT> key
* presses.
* To spare you debug manipulations, I wrote this short program
* If you don't have a 'C' compiler, use the binary I've provided
*
* If you have any questions, or problems, feel free to contact me.
*
* Philip B. Gardner 70053,3157
*/
#include <stdio.h>
#include <string.h>
#include <process.h>
char help[] = "fixdpmi (dpmiload.exe's pathname) [-u]\n"
" -u is optional and reverses the patch" ;
#define datalen 88
unsigned char patch[3][datalen] = {
{
0x5E,0x07,0x1F,0xEB,0x88,0x8C,0xD0,0x8B,
0xDC,0x8B,0xEC,0x8B,0x4E,0x04,0x8B,0x26,
0x0F,0x00,0x8E,0x16,0x07,0x00,0x51,0x83,
0xEB,0x0E,0x53,0x50,0xE8,0x82,0x00,0xE8,
0xA6,0xD1,0xE8,0x19,0xFC,0xE8,0x67,0x00,
0xE8,0x52,0x00,0xE8,0x9A,0x00,0xE8,0xBB,
0x00,0x58,0x5B,0x59,0x8B,0x16,0x0B,0x00,
0x8E,0xC2,0x8B,0x16,0x6C,0x00,0x26,0x89,
0x16,0x10,0x00,0x26,0x89,0x0E,0x0A,0x00,
0x8E,0xC2,0x26,0x89,0x1E,0x2E,0x00,0x26,
0xA3,0x30,0x00,0xB8,0x00,0x4C,0xCD,0x21
},
{
0x5E,0x07,0x1F,0xEB,0x88,0x8C,0xD0,0x89,
0xE5,0xC4,0x4E,0x04,0x8B,0x26,0x0F,0x00,
0x8E,0x16,0x07,0x00,0x50,0x83,0xED,0x0E,
0x55,0x51,0x06,0x90,0xE8,0x82,0x00,0xE8,
0xA6,0xD1,0xE8,0x19,0xFC,0xE8,0x67,0x00,
0xE8,0x52,0x00,0xE8,0x9A,0x00,0xE8,0xBB,
0x00,0x8B,0x16,0x6C,0x00,0x8E,0x1E,0x0B,
0x00,0x89,0x16,0x10,0x00,0x8F,0x06,0x0C,
0x00,0x8F,0x06,0x0A,0x00,0x8E,0xDA,0x8F,
0x06,0x2E,0x00,0x8F,0x06,0x30,0x00,0xEB,
0x00,0xEB,0x00,0xB8,0x00,0x4C,0xCD,0x21
}
} ;
#define start (0x3A68L)
#define broke (patch[0])
#define fixit (patch[1])
#define buffer (patch[2])
void main(int argc, char *argv[])
{
FILE *fp ;
int state ;
char *search = broke ;
char *update = fixit ;
for(state = 4 ; state ; state--)
switch(state) {
case 4:
if (argc < 2) {
puts(help) ;
goto out ;
}
break ;
case 3:
if ((fp = fopen(argv[1],"rb+")) == NULL) {
printf("Unable able to open %s\n",argv[1]) ;
goto out ;
}
if (argc > 2 && argv[2][0] == '-') {
switch(argv[2][1]) {
case 'u':
case 'U':
update = broke ;
search = fixit ;
}
}
break ;
case 2:
if (fseek(fp,start,SEEK_SET)
|| fread(buffer,1,datalen,fp) != datalen
|| memcmp(buffer,search,datalen)) {
printf("Wrong version of %s\n",argv[1]) ;
goto out ;
}
break ;
case 1:
if (fseek(fp,-datalen,SEEK_CUR)
|| fwrite(update,1,datalen,fp) != datalen) {
printf("Error patching %s\n",argv[1]) ;
goto out ;
}
break ;
case 0:
printf("Successfully patched %s\n",argv[1]) ;
}
out:
if (fp != NULL) fclose(fp) ;
exit(state) ;
}
/* ---------- BUG ----------
MOV AX,SS ; segment=int 2Fh vector,offset=386d
MOV BX,SP
MOV BP,SP
MOV CX,[BP+04] ; CX = offset of new termination address
MOV SP,[000F]
MOV SS,[0007]
PUSH CX
SUB BX,+0E ; simulate register storage space of DOS exec
PUSH BX
PUSH AX
CALL 3909 ; undo INT 2Fh
CALL 0A30 ; returns by way of switching to protected mode
CALL 34A6
CALL 38F7
CALL 38E5
CALL 3930
CALL 3954
POP AX
POP BX
POP CX
MOV DX,[000B] ; still in protected mode
MOV ES,DX
MOV DX,[006C]
ES:
MOV [0010],DX
ES:
MOV [000A],CX ; dpmiload's PSP termination address offset
MOV ES,DX
ES:
MOV [002E],BX ; client's last dos stack
ES:
MOV [0030],AX
MOV AX,4C00
INT 21
*/
/* ---------- FIX ----------
MOV AX,SS ; segment=int 2Fh vector,offset=386d
MOV BP,SP
LES CX,[BP+04] ; ES not needed now I'm pretty sure
MOV SP,[000F]
MOV SS,[0007]
PUSH AX
SUB BP,+0E ; simulate register storage space of DOS exec
PUSH BP
PUSH CX ; push full terminate address (ES:CX)
PUSH ES
NOP
CALL 3909 ; undo INT 2Fh
CALL 0A30 ; returns by way of switching to protected mode
CALL 34A6
CALL 38F7
CALL 38E5
CALL 3930
CALL 3954
MOV DX,[006C] ; still in protected mode
MOV DS,[000B]
MOV [0010],DX
POP [000C] ; FIX!! dpmiload's PSP termination address segment
POP [000A] ; dpmiload's PSP termination address offset
MOV DS,DX
POP [002E] ; client's last dos stack
POP [0030]
JMP 38B9
JMP 38BB
MOV AX,4C00 ; exit
INT 21
*/